﻿/**
 * @file mio.c
 * @author septem (jsm920@outlook.com)
 * @brief @see mio.h
 * @version 0.1
 * @date 2025-01-12
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "mio.h"

#if defined(_WIN32) && defined(_MSC_VER)
// #pragma execution_character_set("utf-8")
#define WIN32_LEAN_AND_MEAN // 预处理器宏定义，它告诉编译器仅包含Windows SDK中最常用的函数和数据类型，从而减小编译时间和生成的可执行文件大小。
#include <assert.h>
#include <mswsock.h>
#pragma warning( push )
#pragma warning( disable: 4996 ) // 禁用使用所谓的安全函数告警
//以下代码是用于在 main函数之前执行 (如果是 WinMain printf 不能打印输出到命令行，如果想 输出需要调用 AllocConsole();freopen("CONOUT$", "w", stdout);)
//https://www.cnblogs.com/shokey520/p/3680804.html
// 《windows via c/c++》第4章进程时，里面提到了windows函数的入口函数在crtexe.c的 __tmainCRTStartup() 中
// __tmainCRTStartup() BEGIN => section .CRT$XIA~.CRT$XIZ => section .CRT$XCA~.CRT$XCZ => main() =>
// _onexit/atexit table => section .CRT$XPA~.CRT$XPZ => section .CRT$XTA~.CRT$XTZ => END
// .CRT$XIA~.CRT$XIZ  C initializers 
// .CRT$XCA~.CRT$XCZ C++ initializers
// _onexit/atexi exit functions
// .CRT$XPA~.CRT$XPZ C pre-terminators
// .CRT$XTA~.CRT$XTZ C terminators
//在 main 之前调用 需要参考 以下网址
//https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/crt-initialization?view=msvc-140
//仅用于 win 注销 Windows Socket库
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
LPFN_CONNECTEX lpfnConnectEx = NULL;
void _atuninit(void)
{
    #ifdef _DEBUG
    printf("Begin to exit mio....\n");
    #endif
    WSACleanup();
}
//仅用于 win 安装 Windows Socket库
int _atstart(void)
{
    #ifdef _DEBUG
    #ifdef _WINDOWS
    AllocConsole();freopen("CONOUT$", "w", stdout);
    #endif;
    printf("Begin to execute mio....\n");
    // MessageBoxA(NULL,"xxx","xxx",MB_OK);
    #endif
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
    wVersionRequested = MAKEWORD(2, 2);
    err = WSAStartup(wVersionRequested, &wsaData); //安装
    if (err != 0) {
        /* Tell the user that we could not find a usable */
        /* Winsock DLL.                                  */
        printf("WSAStartup failed with error: %d\n", err);
        return 1;
    }
    atexit(_atuninit);
    // // 用于 初始化 AcceptEx 为后续调用 重叠版的 AcceptEx 做好准备
    SOCKET sock =  socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sock == SOCKET_ERROR)
    {
        return -1;
    }
    GUID GuidAcceptEx = WSAID_ACCEPTEX;
    DWORD dwBytes;
    int iResult = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
             &GuidAcceptEx, sizeof (GuidAcceptEx), 
             &lpfnAcceptEx, sizeof(lpfnAcceptEx), 
             &dwBytes, NULL, NULL);
    if (iResult == SOCKET_ERROR) {
        closesocket(sock);
        return -1;
    }
    GUID GuidConnectEx = WSAID_CONNECTEX;
    iResult = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
             &GuidConnectEx, sizeof (GuidConnectEx), 
             &lpfnConnectEx, sizeof(lpfnConnectEx), 
             &dwBytes, NULL, NULL);
    if (iResult == SOCKET_ERROR) {
        closesocket(sock);
        return -1;
    }
    closesocket(sock);
    return 0;
}
typedef int  (__cdecl  *_PIFV)(void);
#pragma section(".CRT$XIX",long,read)
__declspec(allocate(".CRT$XIX")) _PIFV __xi_x = _atstart ;

#elif defined(__linux__)
//#define _POSIX_C_SOURCE 199309L // 因为一直报 CLOCK_MONOTONIC 未声明
// #define _XOPEN_SOURCE 500 // 因为一直报 CLOCK_MONOTONIC 未声明
#define _DEFAULT_SOURCE 1 // 因为一直报 CLOCK_MONOTONIC 未声明 ip_mreq
#include <netinet/in.h>
#undef _DEFAULT_SOURCE
#include <stdio.h>
#include <string.h> //strcpy()
#include <stdlib.h> //malloc() free() realloc()
#include <unistd.h> // close()
#include <stdarg.h> // va_list va_start() va_arg() va_end()
#include <assert.h> // assert()
#include <errno.h> // errno
#include <signal.h> //EINTR
#include <sys/socket.h>
#include <sys/epoll.h> // epoll_create() epoll_ctl
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <sys/timerfd.h> // timerfd_create() timerfd_settime() timerfd_gettime()
#include <time.h>  // struct itimerspec
#include <limits.h> // ULLONG_MAX
#include <sys/eventfd.h> //eventfd()
#include <semaphore.h> // sem_t
#define SOCKET int  //  定义套接字 为 SOCKET 与 windows 下相同,减少代码量
#define SOCKET_ERROR -1 // 定义套接字失败 SOCKET_ERROR 为 -1 与 windows 下相同,减少代码量
#define closesocket(sock) close((sock)) // 定义关闭套接字为 closesocket 与 windows 下相同,减少代码量
#ifndef NDEBUG
// gcc 在 main 之前执行
__attribute__ ((constructor)) void _Startup_initial(void) 
{
    printf("Begin to exit mio....\n");
}
// gcc 在 main 这后执行
__attribute__ ((destructor))void _Cleanup(void)
{
    printf("Begin to exit mio....\n");
}
#endif
#endif

#ifndef NDEBUG
int DebugPrint(const char* format, ...)
{
    int rlen = 0;
    #if defined(_WIN32) && defined(_MSC_VER)
    SYSTEMTIME st;
    GetLocalTime(&st);
    #elif defined(__linux__)
    struct timespec tp= {0};
    clock_gettime(CLOCK_REALTIME,&tp);
    struct tm* ptm = localtime(&tp.tv_sec);
    #endif
    rlen = printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ",
        #if defined(_WIN32) && defined(_MSC_VER)
            st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds
        #elif defined(__linux__)
            ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,
            ptm->tm_hour,ptm->tm_min,ptm->tm_sec,
            tp.tv_nsec / ((long)(1e9/1e3))
        #endif
            );
    va_list va;
    va_start(va, format);
    rlen += vprintf(format,va);
    va_end(va);
    fflush(stdout);
    return rlen;
}
#endif

mio_t* MioMalloc(int maxMio, int cntThread)
{
    unsigned int _szMem = MioMemUsed(maxMio);
    mio_t* _pmio = (mio_t*)malloc(_szMem);
    if(_pmio == NULL)
    {
        return NULL;
    }
    #if defined(_WIN32) && defined(_MSC_VER)
    _pmio->epfd = NULL;
    #elif defined(__linux__)
    _pmio->epfd = -1;
    #endif
    if(NULL == ( _pmio = MioInit(_pmio, maxMio, cntThread)))
    {
        free(_pmio);
        _pmio = NULL;
    }
    return _pmio;
}
mio_t* MioInit(mio_t* pmio,int maxMio, int cntThread)
{
    // pmio->pstackPbuf = (stack_t *)((char*)pmio + sizeof(mio_t));
    pmio->plistContext = (list_t*)((char*)pmio + sizeof(mio_t) /*+ Array2MemUsed()*/);
    if(/*NULL == Array2Init(pmio->pstackPbuf, sizeof(char*), maxMio) ||*/
        NULL == ListInit(pmio->plistContext, sizeof(miocontext_t),maxMio))
    {
        return NULL;
    }
    #if defined(_WIN32) && defined(_MSC_VER)
    pmio->epfd = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, cntThread); // IOCP 句柄
    if(pmio->epfd == NULL)
    {
        ListUninit(pmio->plistContext);
        return NULL;
    }
    #elif defined(__linux__)
    pmio->epfd = epoll_create(1024);
    if(pmio->epfd == -1)
    {
        ListUninit(pmio->plistContext);
        return NULL;
    }
    #endif
    return pmio;
}
void MioUninit(mio_t* pmio)
{
    for(listnode_t* pln = ListFront(pmio->plistContext); pln != NULL; pln = ListNodeNext(pln))
    {
        miocontext_t * pmioc = ListNodeData(pln);
        #if defined(_WIN32) && defined(_MSC_VER)
        CancelIoEx((HANDLE)pmioc->sock, &pmioc->olRecv);
         closesocket(pmioc->sock);
        #elif defined(__linux__)
        close(pmioc->sock);
        #endif
        pmioc->sock = SOCKET_ERROR;
        #if defined(_WIN32) && defined(_MSC_VER)
        if(pmioc->type == MIO_TYPE_TCPS)
        {
            if(pmioc->d.tcps.sock !=  SOCKET_ERROR) 
            {
                closesocket(pmioc->d.tcps.sock);
                pmioc->d.tcps.sock = SOCKET_ERROR;
            }
        }
        else if(pmioc->type == MIO_TYPE_TCP)
        {

        }
        #elif defined(__linux__)
        #endif

    }
    ListUninit(pmio->plistContext);
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmio->epfd != NULL)
    {
        CloseHandle(pmio->epfd);
        pmio->epfd = NULL;
    }
    #elif defined(__linux__)
    if(pmio->epfd != 1)
    {
        close(pmio->epfd);
        pmio->epfd = -1;
    }
    #endif
}
void MioFree(mio_t* pmio)
{
    MioUninit(pmio);
    free(pmio);
}

miocontext_t* MioWait(mio_t* pmio, int timeout)
{
    miocontext_t* _pmioc = NULL;
    #if defined(_WIN32) && defined(_MSC_VER)
    DWORD NumberOfBytesTransferred;
    LPOVERLAPPED lpOverlapped = NULL;
    if(FALSE == GetQueuedCompletionStatus((HANDLE)pmio->epfd,&NumberOfBytesTransferred, (PULONG_PTR)&_pmioc,&lpOverlapped, timeout))
    {
        int r = GetLastError();
        if(r == WAIT_TIMEOUT) //超时
        {
            return MIO_EVENT_TIMEOUT;
        }
        else if(r == ERROR_SEM_TIMEOUT || r == ERROR_CONNECTION_REFUSED || r == ERROR_NETWORK_UNREACHABLE) 
        {// 超时//连接被拒 // 网络不可用
            return _pmioc;
        }
        return MIO_EVENT_ERR;
    }
    _pmioc->szRecv = NumberOfBytesTransferred;
    #elif defined(__linux__)
    struct epoll_event ev = {}; // 一次只等待一个事件
    switch (epoll_wait(pmio->epfd, &ev, 1, timeout))
    {
    case -1: //出错
        #ifndef NDEBUG
        if(errno == EINTR) { return MIO_EVENT_INTR; } //注意使用信号例如alarm()而未捕捉信号可能会使epoll_wait返回EINTR错误
        #endif
        return MIO_EVENT_ERR;
    case 0:
        return MIO_EVENT_TIMEOUT;
    case 1:
        _pmioc = ev.data.ptr;
        break;
    } ;
    _pmioc->ev = ev.events;
    #endif
    return _pmioc;
}
/**
 * @brief 申请一个 miocontext_t* 
 * 
 * @param pmio 
 * @return miocontext_t* 
 */
miocontext_t* MioAllocContext(mio_t* pmio)
{ 
    miocontext_t* pmioc = (miocontext_t*)ListPush(pmio->plistContext, NULL);
    if(pmioc)
    {
        memset(pmioc, 0, sizeof(pmioc));
    }
    return pmioc;
}

// int _MioFreeContext_compar(const void*ptr1, const void*ptr2)
// {
//     if((miocontext_t*)ptr1 == (miocontext_t*)ptr2)
//     {
//         return 0;
//     }
//     return -1;
// }

// void MioFreeContext(mio_t* pmio, miocontext_t* pmioc)
// {
//     listnode_t* pln = ListSearch(pmio->plistContext, pmioc, _MioFreeContext_compar);
//     if(pln)
//     {
//         ListErase(pmio->plistContext, pln,1);
//     }
// }

int MioSetBuf(mio_t* pmio,miocontext_t* pmioc, unsigned int szRecvBuf)
{
    if( ! (pmioc->type & MIO_HAS_BUF))
    {
        return 0;
    }
    char* pbuf = (char*)realloc( pmioc->d.tcp.pbufRecv, szRecvBuf);
    if(pbuf == NULL)
    {
        return -1;
    }
    // pmioc->d.tcp.signMallocRecvBuf = 0; //防止未初始化
    if(szRecvBuf)
    {
        if( pmioc->type  == MIO_TYPE_TCP || pmioc->type == MIO_TYPE_TCP_CONNECTING)
        {
            pmioc->d.tcp.pbufRecv = pbuf;
            pmioc->d.tcp.szBufRecv = szRecvBuf;
        }
        else if( pmioc->type == MIO_TYPE_UDP)
        {
            pmioc->d.udp.pbufRecv = pbuf;
            pmioc->d.udp.szBufRecv = szRecvBuf;
        }
    }
    return szRecvBuf;
}

int MioSetBufPtr(mio_t* pmio,miocontext_t* pmioc, char* pRecvBuf, unsigned int szRecvBuf,int mask)
{
    switch (pmioc->type & 0x7FFFF)
    {
    case MIO_TYPE_TCP:
        if((mask) ) 
        {
           if(pmioc->d.tcp.pbufRecv) {free(pmioc->d.tcp.pbufRecv);pmioc->d.tcp.pbufRecv = NULL;}
        }
        else
        {
            pmioc->d.tcp.pbufRecv = pRecvBuf;
            pmioc->d.tcp.szBufRecv = szRecvBuf;
        }
        break;
    case MIO_TYPE_UDP:    
        if((mask) ) 
        {
           if(pmioc->d.udp.pbufRecv) {free(pmioc->d.udp.pbufRecv);pmioc->d.udp.pbufRecv = NULL;}
        }
        else
        {
            pmioc->d.udp.pbufRecv = pRecvBuf;
            pmioc->d.udp.szBufRecv = szRecvBuf;
        }
        break;
    }
    return 0;
}

int MioGetBuf(miocontext_t* pmioc,char** ppRecvBuf, unsigned int *pszRecvBuf)
{
    switch (pmioc->type & 0x7FFFF)
    {
    case MIO_TYPE_TCP:
        if(ppRecvBuf) {(*ppRecvBuf) = pmioc->d.tcp.pbufRecv;}
        if(pszRecvBuf) {(*pszRecvBuf) = pmioc->d.tcp.szBufRecv;}
        return pmioc->d.tcp.szBufRecv;
        break;
    case MIO_TYPE_UDP:    
        if(ppRecvBuf) {(*ppRecvBuf) = pmioc->d.udp.pbufRecv;}
        if(pszRecvBuf) {(*pszRecvBuf) = pmioc->d.udp.szBufRecv;}
        return pmioc->d.udp.szBufRecv;
        break;
    }  
    return -1;
}

unsigned int MioHostIpv4(char* ipv4)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    return ntohl(inet_addr(ipv4));
    #elif defined(__linux__)
    return (unsigned int)inet_network(ipv4);
    #endif
}

char* MioStringIpv4(unsigned int ipv4, char* str)
{
    struct in_addr addr = {.s_addr = htonl(ipv4),};
    char* s = inet_ntoa(addr);
    return strcpy(str, s);
}

// char* MioGetRecv(miocontext_t* pmioc)
// {
//     if(pmioc->type & MIO_HAS_BUF)
//     {
//         return pmioc->d.tcp.pbufRecv;
//     }
//     return NULL;
// }

// int MioGetRecvLen(miocontext_t* pmioc)
// {
//     return (int)pmioc->szRecv;
// }

// int MioSend(miocontext_t* pmioc, const char *buf, int len)
// {
//     return send(pmioc->sock, buf, len, 0);
// }

// int MioSendto(miocontext_t* pmioc,unsigned int rip, unsigned short rport, const char *buf, int len)
// {
//     struct sockaddr_in raddr = {.sin_family = AF_INET, .sin_port = htons(rport), .sin_addr.s_addr = rip, };
//     return sendto(pmioc->sock, buf, len, 0, (const struct sockaddr *)&raddr, sizeof(struct sockaddr_in));
// }

// void MioCloseContext(mio_t* pmio,miocontext_t* pmioc)
// {
//     if(pmioc->sock != SOCKET_ERROR)
//     {
//         closesocket(pmioc->sock);
//         pmioc->sock = SOCKET_ERROR;
//     }
//     if((pmioc->type & MIO_HAS_BUF) )
//     {
//         if(/*pmioc->d.tcp.signMallocRecvBuf && */ pmioc->d.tcp.pbufRecv)
//         {
//             free(pmioc->d.tcp.pbufRecv);
//             pmioc->d.tcp.pbufRecv = NULL;
//         }
//     }
//     MioFreeContext(pmio,pmioc);
// }

miocontext_t* MioTCPSOpen(mio_t* pmio, unsigned int lip, unsigned short lport, int backlog)
{
    // 从 mio_t 分配一个 数据
    miocontext_t* _pmioc = MioAllocContext(pmio);
    if(_pmioc != NULL)
    {
        miocontext_t* _pmioc2 = MioTCPSInit(pmio,_pmioc,lip,lport, backlog);
        if(_pmioc2 == NULL)
        {
            ListErase(pmio->plistContext, ListNode(_pmioc),1 );
            return NULL;
        }
        else if(_pmioc2 != _pmioc)
        {
            ListErase(pmio->plistContext, ListNode(_pmioc),1 );
            return _pmioc2;
        }
    }
    return _pmioc;
}
miocontext_t* MioTCPSInit(mio_t* pmio,miocontext_t*_pmioc,unsigned int lip, unsigned short lport, int backlog)
{
    // 检查 是否已经有 lip:lport
    for(listnode_t* pln = ListFront(pmio->plistContext); pln != NULL; pln = ListNodeNext(pln) )
    {
        miocontext_t* pmioc = (miocontext_t*)ListNodeData(pln);
        if(pmioc->type == MIO_TYPE_TCPS && pmioc->d.tcps.lip == lip && pmioc->d.tcps.lport == lport)
        {
            return pmioc;
        }
    }
    // 没有就开始新建一个
    #if defined(_WIN32) && defined(_MSC_VER)
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //默认有重叠属性的套接字，此处不需要使用 WSASocket 创建
    #elif defined(__linux__)
    int sock = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP); //非阻塞套接字
    #endif
    if(sock == SOCKET_ERROR)
    {
        return NULL;
    }
    
    struct sockaddr_in laddr = {.sin_family = AF_INET, .sin_port=htons(lport), .sin_addr.s_addr = htonl(lip)};
    if(SOCKET_ERROR == bind(sock,( const struct sockaddr*)&laddr,sizeof(struct sockaddr_in)))
    {
        closesocket(sock);
        return NULL;
    }
    if(SOCKET_ERROR == listen(sock,backlog))
    {
        closesocket(sock);
        return NULL;
    }
    _pmioc->d.tcps.lip = lip; _pmioc->d.tcps.lport = lport;
    // _pmioc->events = EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT;
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmio->epfd != CreateIoCompletionPort((HANDLE)sock, pmio->epfd, (ULONG_PTR)_pmioc,0))
    {
        closesocket(sock);
        return NULL;
    }
    #elif defined(__linux__)
    // ev 初始添加到 epoll 不触发 accept,需要调用 overload才可以触发
    struct epoll_event ev = {.events= /*EPOLLIN |*/ EPOLLET|EPOLLERR | EPOLLRDHUP |EPOLLONESHOT, .data.ptr = _pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,sock, &ev) )
    {
        closesocket(sock);
        return NULL;
    }
    #endif
    _pmioc->type = MIO_TYPE_TCPS;
    _pmioc->sock = sock;
    return _pmioc;
}

int MioTCPSClose(mio_t* pmio, miocontext_t* pmiocTCPS)
{
    int ret = MioTCPSUninit(pmio, pmiocTCPS);
    ListErase(pmio->plistContext, ListNode(pmiocTCPS),1 );
    return ret;
}
int MioTCPSUninit(mio_t* pmio, miocontext_t* pmiocTCPS)
{
    int ret = 0;
    if(pmiocTCPS)
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        CancelIo((HANDLE )pmiocTCPS->sock);
        ret = closesocket(pmiocTCPS->sock);
        return 0;
        #elif defined(__linux__)
        
        int r = 0;
        if(-1 == (r = epoll_ctl(pmio->epfd, EPOLL_CTL_DEL,pmiocTCPS->sock, NULL)))
        {
            ret = -1;
        }
        if(-1 == (r = close( pmiocTCPS->sock)))
        {
            ret = -1;
        }
        #endif
        pmiocTCPS->sock = -1;
        ListErase(pmio->plistContext, ListNode(pmiocTCPS),1 );
    }
    return ret;  
    
}

int MioTCPSOverlapped(mio_t* pmio, miocontext_t* pmioc)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    if(SOCKET_ERROR == (pmioc->d.tcps.sock =  socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
    {
        return -1;
    }
    if(FALSE == lpfnAcceptEx(pmioc->sock,
                            pmioc->d.tcps.sock, 
                            pmioc->d.tcps.laddr,0,
                            sizeof(struct sockaddr_in) + 16, 
                            sizeof(struct sockaddr_in) + 16, 
                            &pmioc->szRecv, 
                            &pmioc->olRecv))
    {
        if(WSAGetLastError () != ERROR_IO_PENDING)
        {
            closesocket(pmioc->d.tcps.sock);
            pmioc->d.tcps.sock = SOCKET_ERROR;
            return -1;
        }
    }
    #elif defined(__linux__)
    // 边缘触发,多个事件只触发一次,配合 EPOLLONESHOT
    struct epoll_event ev = {.events=EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_MOD,pmioc->sock, &ev) )
    {
        return -1;
    }
    #endif
    return 0;
}

miocontext_t* MioTCPSAccept(mio_t* pmio, miocontext_t* pmiocTCPS)
{
    // 从 mio_t 分配一个 数据
    miocontext_t* _pmioc = MioAllocContext(pmio);
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmio == NULL)
    {
        closesocket(pmiocTCPS->d.tcps.sock);
        return NULL;
    }
    if(pmio->epfd != CreateIoCompletionPort((HANDLE)pmiocTCPS->d.tcps.sock, pmio->epfd, (ULONG_PTR)_pmioc,0))
    {
        ListErase(pmio->plistContext, ListNode(_pmioc),1 );
        closesocket(pmiocTCPS->d.tcps.sock);
        return NULL;
    }
    _pmioc->type = MIO_TYPE_TCP;
    _pmioc->sock = pmiocTCPS->d.tcps.sock;
    pmiocTCPS->d.tcps.sock = SOCKET_ERROR;
    #elif defined(__linux__)
    if(_pmioc == NULL)
    {
        return NULL;
    }
    socklen_t addrlen = sizeof(struct sockaddr);
    int sock = accept(pmiocTCPS->sock, (struct sockaddr *)&pmiocTCPS->d.tcps.raddr, &addrlen);
    if(sock == -1)
    {
        ListErase(pmio->plistContext, ListNode(_pmioc),1 );; return NULL;
    }
    _pmioc->type = MIO_TYPE_TCP;
    _pmioc->sock = sock;
    _pmioc->d.tcp.pmiocTCPS = pmiocTCPS;
    // _pmioc->events = EPOLLIN |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT;
    struct epoll_event ev = {.events = EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = _pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,sock, &ev))
    {
        close(sock); ListErase(pmio->plistContext, ListNode(_pmioc),1 );; return NULL;
    }
    #endif
    return _pmioc;
}

miocontext_t* MioTCPOpen(mio_t* pmio,unsigned int lip, unsigned short lport,unsigned int rip, unsigned short rport)
{
    // 从 mio_t 分配一个 数据
    miocontext_t* _pmioc = MioAllocContext(pmio);
    if(pmio != NULL)
    {
        if(NULL == MioTCPInit(pmio,_pmioc,lip,lport,rip,rport))
        {
            ListErase(pmio->plistContext,ListNode(_pmioc),1);_pmioc=NULL;
        }
    }
    return _pmioc;
}
miocontext_t* MioTCPInit(mio_t* pmio,miocontext_t*_pmioc,unsigned int lip, unsigned short lport,unsigned int rip, unsigned short rport)
{
    assert(rip && rport);
    SOCKET sock = socket(AF_INET, SOCK_STREAM 
    #if defined(__linux__)
    | SOCK_NONBLOCK 
    #endif
    ,IPPROTO_TCP);
    if(SOCKET_ERROR == sock)
    {
        return NULL;
    }
    struct sockaddr_in laddr = {.sin_family = AF_INET, .sin_port=htons(lport), .sin_addr.s_addr = htonl(lip)};
    if(SOCKET_ERROR == bind(sock,( const struct sockaddr*)&laddr,sizeof(struct sockaddr_in)))
    {
        closesocket(sock);
        return NULL;
    }
    _pmioc->type = MIO_TYPE_TCP_CONNECTING;
    _pmioc->sock = sock;
    _pmioc->d.tcp.rip = rip;
    _pmioc->d.tcp.rport = rport;
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmio->epfd != CreateIoCompletionPort((HANDLE)_pmioc->sock, pmio->epfd, (ULONG_PTR)_pmioc,0))
    {
        closesocket(_pmioc->sock);
        return NULL;
    }
    #elif defined(__linux__)
    //
    struct epoll_event ev = {.events = /*EPOLLIN| */ EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = _pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,sock, &ev))
    {
        close(sock);
    }
    #endif
    return _pmioc;
}

int MioTCPClose(mio_t* pmio, miocontext_t* pmiocTCP)
{
    int ret = MioTCPUninit(pmio,pmiocTCP);
    ListErase(pmio->plistContext, ListNode(pmiocTCP),1 );
    return ret;
}
int MioTCPUninit(mio_t* pmio, miocontext_t* pmiocTCP)
{
    int ret = 0;
    if(pmiocTCP)
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        CancelIo((HANDLE )pmiocTCP->sock);
        ret = closesocket(pmiocTCP->sock);
        #elif defined(__linux__)
        if(-1 == (r = epoll_ctl(pmio->epfd, EPOLL_CTL_DEL,pmiocTCP->sock, NULL)))
        {
            ret = -1;
        }
        if(-1 == (r = close( pmiocTCP->sock)))
        {
            ret = -1;
        }
        #endif
        if(pmiocTCP->d.tcp.pbufRecv) {free(pmiocTCP->d.tcp.pbufRecv);pmiocTCP->d.tcp.pbufRecv=NULL;}
    }
    return ret;
}

int MioTCPOverlapped(mio_t* pmio, miocontext_t* pmioc)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    if(FALSE == ReadFile((HANDLE)pmioc->sock,pmioc->d.tcp.pbufRecv,pmioc->d.tcp.szBufRecv, &pmioc->szRecv, &pmioc->olRecv))
    {
        if(WSAGetLastError () != ERROR_IO_PENDING)
        {
            return -1;
        }
    }
    #elif defined(__linux__)
    // 边缘触发,多个事件只触发一次,配合 EPOLLONESHOT
    struct epoll_event ev = {.events =EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_MOD,pmioc->sock, &ev) )
    {
        return -1;
    }
    #endif
    return 0;
}

int MioTCPConnectStatus( miocontext_t* pmioc)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    if( MIO_TYPE_TCP_CONNECTING == pmioc->type)
    {
        int x  = GetLastError();
        if (x == 0) // 连接成功
        {
            pmioc->type = MIO_TYPE_TCP;
            return 0;
        }
        else if( x == WSAETIMEDOUT || x == ERROR_SEM_TIMEOUT) //连接超时
        {
            return WSAETIMEDOUT;
        }
        else if( x == WSAECONNREFUSED || x == ERROR_CONNECTION_REFUSED) //对方拒绝连接
        {
            return WSAECONNREFUSED;
        }
        else if( x == WSAENETUNREACH || x ==ERROR_NETWORK_UNREACHABLE) //	此时不可以从此主机访问该网络。 
        {
            return WSAENETUNREACH;
        }
        else
        {
            return -1;
        }
    }
    #elif defined(__linux__)
    if( MIO_TYPE_TCP_CONNECTING == pmioc->type)
    {
        int err = 0;
        socklen_t err_len = sizeof(err);
        getsockopt(pmioc->sock, SOL_SOCKET, SO_ERROR, &err, &err_len);
        if(err == 0){pmioc->type = MIO_TYPE_TCP;return 0;}
        if(err == ECONNREFUSED) {return MIO_TCP_REFUSED;} //拒绝
        else if (err == ETIMEDOUT) {return MIO_TCP_TIMEOUT;} //超时,即服务器无响应
        else if (err == ENETUNREACH || err == EHOSTUNREACH) {return MIO_TCP_NETUNREACH;} //网络不可达/没有路由达到,一般是网卡禁用或局域网中无此IP
    }
    #endif
    return 0;
}

int MioTCPConnect(mio_t* pmio,miocontext_t* pmioc)
{
    pmioc->type = MIO_TYPE_TCP_CONNECTING;
    struct sockaddr_in raddr = {.sin_family = AF_INET, .sin_port=htons(pmioc->d.tcp.rport), .sin_addr.s_addr = htonl(pmioc->d.tcp.rip),};
    #if defined(_WIN32) && defined(_MSC_VER)
    if( MIO_TYPE_TCP_CONNECTING == pmioc->type)
    {
        if(FALSE == lpfnConnectEx(pmioc->sock, (const struct sockaddr *)&raddr, sizeof(struct sockaddr_in),NULL,0,NULL,&pmioc->olRecv))
        {
            int x = WSAGetLastError();
            if(WSAGetLastError() != ERROR_IO_PENDING)
            {
                return -1;
            }
            SetLastError(0);
        }
    }
    #elif defined(__linux__)
    struct epoll_event ev = {.events = EPOLLOUT | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_MOD,pmioc->sock, &ev))
    {
        return -1;
    }
    if( -1 == connect(pmioc->sock, (const struct sockaddr *)&raddr, sizeof(struct sockaddr_in)))
    {
        if(errno == EINPROGRESS){return 0;}
        return -1;
    }
    #endif
    return 0;
}

int MioTCPRecv(miocontext_t* pmioc, char** ppdata, int* plen)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    pmioc->szRecv = recv(pmioc->sock, pmioc->d.tcp.pbufRecv, pmioc->d.tcp.szBufRecv, 0);
    if(pmioc->szRecv < 0)
    {
        if(ppdata)
        {
            (*ppdata) = NULL;
        }
        if(*plen)
        {
            (*plen) = pmioc->szRecv;
        }
        return -1;
    }
    if(ppdata)
    {
        (*ppdata) = pmioc->d.tcp.pbufRecv;
    }
    if(plen)
    {
        (*plen) = pmioc->szRecv;
    }
    #endif
    return (int)pmioc->szRecv;
}

int MioTCPSend(miocontext_t* pmioc, char* data, int len)
{
    return send(pmioc->sock, data, len, 0);
}

miocontext_t* MioUDPOpen(mio_t* pmio,unsigned int lip, unsigned short lport)
{
    // 从 mio_t 分配一个 数据
    miocontext_t* _pmioc = MioAllocContext(pmio);
    if(pmio != NULL)
    {
        miocontext_t* _pmioc2 = MioUDPInit(pmio,_pmioc,lip,lport);
        if(NULL == _pmioc2)
        {
            ListErase(pmio->plistContext,ListNode(_pmioc),1);
            _pmioc = NULL;
        }
        else if(_pmioc2 !=_pmioc )
        {
             ListErase(pmio->plistContext,ListNode(_pmioc),1);
             return _pmioc2;
        }
    }
    return _pmioc;
}
miocontext_t* MioUDPInit(mio_t* pmio, miocontext_t* _pmioc,unsigned int lip, unsigned short lport)
{
    // 检查 是否已经有 lip:lport
    if(lip != 0 && lport != 0)
    {
        for(listnode_t* pln = ListFront(pmio->plistContext); pln != NULL; pln = ListNodeNext(pln) )
        {
            miocontext_t* pmioc = (miocontext_t*)ListNodeData(pln);
            if(pmioc->type == MIO_TYPE_UDP && pmioc->d.udp.lip == lip && pmioc->d.udp.lport == lport)
            {
                return pmioc;
            }
        }
    }
    #if defined(_WIN32) && defined(_MSC_VER)
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //创建 一个 重叠 socket（socket()默认重叠）
    #elif defined(__linux__)
    SOCKET sock = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP); //创建 一个非阻塞 socket
    #endif
    if(SOCKET_ERROR == sock)
    {
        return NULL;
    }
    struct sockaddr_in laddr = {.sin_family = AF_INET, .sin_port=htons(lport), .sin_addr.s_addr = htonl(lip)};
    if(SOCKET_ERROR == bind(sock,( const struct sockaddr*)&laddr,sizeof(struct sockaddr_in)))
    {
        closesocket(sock);
        return NULL;
    }
    _pmioc->type = MIO_TYPE_UDP;
    _pmioc->sock = sock;
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmio->epfd != CreateIoCompletionPort((HANDLE)_pmioc->sock, pmio->epfd, (ULONG_PTR)_pmioc,0))
    {
        closesocket(_pmioc->sock);
        return NULL;
    }
    #elif defined(__linux__)
    // 边缘触发,多个事件只触发一次,配合 EPOLLONESHOT
    struct epoll_event ev = {.events =/*EPOLLIN | */EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = _pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,_pmioc->sock, &ev) )
    {
        closesocket(_pmioc->sock);
        return NULL;
    }
    #endif
    return _pmioc;
}

int MioUDPClose(mio_t* pmio, miocontext_t* pmiocUDP)
{
    int ret = MioUDPUninit(pmio,pmiocUDP);
    ListErase(pmio->plistContext, ListNode(pmiocUDP),1 );
    return ret;
}

int MioUDPUninit(mio_t* pmio, miocontext_t* pmiocUDP)
{
    int ret = 0;
    if(pmiocUDP)
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        CancelIo((HANDLE )pmiocUDP->sock);
        ret = closesocket(pmiocUDP->sock);
        #elif defined(__linux__)
        int ret = 0;
        int r = 0;
        if(-1 == (r = epoll_ctl(pmio->epfd, EPOLL_CTL_DEL,pmiocUDP->sock, NULL)))
        {
            ret = -1;
        }
        if(-1 == (r = close( pmiocUDP->sock)))
        {
            ret = -1;
        }
        #endif
    }
    if(pmiocUDP->d.udp.pbufRecv) {free(pmiocUDP->d.udp.pbufRecv);pmiocUDP->d.udp.pbufRecv=NULL;}
    return ret;
}

int MioUDPOverlapped(mio_t* pmio, miocontext_t* pmioc)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    if(FALSE == ReadFile((HANDLE)pmioc->sock,pmioc->d.udp.pbufRecv,pmioc->d.udp.szBufRecv, &pmioc->szRecv, &pmioc->olRecv))
    {
        if(WSAGetLastError () != ERROR_IO_PENDING)
        {
            return -1;
        }
    }
    #elif defined(__linux__)
    struct epoll_event ev = {.events = EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_MOD,pmioc->sock, &ev) )
    {
        return -1;
    }
    #endif
    return 0;
}

int MioUDPRecv(miocontext_t* pmioc, char** ppdata, int*plen, unsigned int* prip,unsigned short* prport)
{
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    struct sockaddr_in raddr = {0};
    socklen_t addr_len = sizeof(struct sockaddr_in);
    pmioc->szRecv = recvfrom(pmioc->sock, pmioc->d.tcp.pbufRecv, pmioc->d.tcp.szBufRecv,0, (struct sockaddr *)&raddr,&addr_len);
    if(pmioc->szRecv < 0)
    {
        if(ppdata) { (*ppdata) = NULL; }
        if(plen) { (*plen) = pmioc->szRecv; }
        if(prip) {(*prip) = ntohl(raddr.sin_addr.s_addr);}
        if(prip) {(*prport) = ntohs(raddr.sin_port);}
        return -1;
    }
    if(ppdata) { (*ppdata) = pmioc->d.tcp.pbufRecv; }
    if(plen) { (*plen) = pmioc->szRecv; }
    if(prip) {(*prip) = ntohl(raddr.sin_addr.s_addr);}
    if(prip) {(*prport) = ntohs(raddr.sin_port);}
    #endif
    return (int)pmioc->szRecv;
}

int MioUDPSend(miocontext_t* pmioc, char* data, int len, unsigned int rip,unsigned short rport)
{
    struct sockaddr_in raddr = {.sin_family=AF_INET,.sin_port=htons(rport),.sin_addr.s_addr = htonl(rip),};
    socklen_t addr_len = sizeof(struct sockaddr_in);
    return sendto(pmioc->sock, data, len, 0, (struct sockaddr *)&raddr, addr_len);
}

int MioUDPConnect(mio_t* pmio, miocontext_t* pmioc,unsigned int rip, unsigned short rport)
{
    struct sockaddr_in raddr = {.sin_family = AF_INET, .sin_port = htons(rport), .sin_addr.s_addr =htonl(rip), };
    return connect(pmioc->sock, (const struct sockaddr *)&raddr, sizeof(struct sockaddr_in));
}

int MioUDPSetBroadcast(miocontext_t* pmioc, int enable)
{
    return setsockopt(pmioc->sock, SOL_SOCKET, SO_BROADCAST, (const char*)&enable, sizeof(int));
}
int MioUDPSetMulticastLoop(miocontext_t* pmioc,int loop)
{
    return setsockopt(pmioc->sock,IPPROTO_IP, IP_MULTICAST_LOOP,(const char*)&loop, sizeof(int));
}
int MioUDPSetMulticastTTL(miocontext_t* pmioc,int ttl)
{
    return setsockopt(pmioc->sock,IPPROTO_IP, IP_MULTICAST_TTL,(const char*)&ttl, sizeof(int));
}
int MioUDPSetMulticastIF(miocontext_t* pmioc,unsigned int lip)
{
    struct in_addr raddr = {.s_addr = lip,};
    return setsockopt(pmioc->sock,IPPROTO_IP, IP_MULTICAST_TTL,(const char*)&raddr, sizeof(struct in_addr));
}
int MioUDPSetMulticast(miocontext_t* pmioc, unsigned int mip, unsigned int lip, int add)
{
    struct ip_mreq mreq = {.imr_multiaddr.s_addr = mip,.imr_interface.s_addr = lip};
    return (setsockopt(pmioc->sock, IPPROTO_IP, add?IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(struct ip_mreq)));
}
#if defined(_WIN32) && defined(_MSC_VER)
unsigned long long GetTimeNow()
{
    SYSTEMTIME SystemTime;
    FILETIME filetime;
    GetLocalTime(&SystemTime);
    SystemTimeToFileTime(&SystemTime,&filetime);
    return ((((unsigned long long)filetime.dwHighDateTime) << (sizeof(filetime.dwLowDateTime)*8)) | filetime.dwLowDateTime);
}

VOID CALLBACK _MioTimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
    miocontext_t * _pmioc = (miocontext_t *)lpParam;
    mio_t* _pmio = _pmioc->d.timer.pmio;
    miotimer_t* _pmiot = _pmioc->d.timer.pmiot; //当前计计已超时的 定时器
    PostQueuedCompletionStatus(((HANDLE)_pmio->epfd),TimerOrWaitFired,(ULONG_PTR)_pmioc,&_pmioc->olRecv);
}
#endif
miocontext_t* MioTimerOpen(mio_t* pmio)
{
    miocontext_t* _pmioc = MioAllocContext(pmio);
    if(_pmioc )
    {
        if(NULL == MioTimerInit(pmio,_pmioc))
        {
            ListErase(pmio->plistContext,ListNode(_pmioc),1);_pmioc=NULL;
        }
    }
    return _pmioc;
}
miocontext_t* MioTimerInit(mio_t* pmio, miocontext_t*_pmioc)
{
    if(NULL == Array2Init(&_pmioc->d.timer.arrTimer, sizeof(miotimer_t), 32))
    {
        ListErase(pmio->plistContext, ListNode(_pmioc),1 );
        return NULL;
    }
    #if defined(_WIN32) && defined(_MSC_VER)
    _pmioc->sock = (SOCKET)NULL;
    _pmioc->d.timer.pmio = pmio;
    _pmioc->type = MIO_TYPE_TIMER;
    _pmioc->d.timer.ID = 1;
    #elif defined(__linux__)
    struct timespec now = {0}; // 实时墙上时间UTC
    struct timespec boot = {0}; // 启动时到当前的时间
    clock_gettime(CLOCK_REALTIME_COARSE, &now); 
    clock_gettime(CLOCK_MONOTONIC_COARSE, &boot);
    _pmioc->d.timer.base.tv_sec = now.tv_sec - boot.tv_sec;
    if(now.tv_nsec < boot.tv_nsec)
    {
        _pmioc->d.timer.base.tv_sec --;
        _pmioc->d.timer.base.tv_nsec = (long)(1E+09) + now.tv_nsec - boot.tv_nsec;
    }
    else
    {
        _pmioc->d.timer.base.tv_nsec = now.tv_nsec - boot.tv_nsec;
    }
    _pmioc->sock = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    if(_pmioc->sock == -1)
    {
        ListErase(pmio->plistContext, ListNode(_pmioc),1 );
        Array2Uninit(&_pmioc->d.timer.arrTimer);
        return NULL;
    }
    _pmioc->type = MIO_TYPE_TIMER;
    _pmioc->d.timer.ID = 1;
    struct epoll_event ev = {.events = /*EPOLLIN |*/ EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = _pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,_pmioc->sock, &ev) )
    {
        close(_pmioc->sock );
        Array2Uninit(&_pmioc->d.timer.arrTimer);
        ListErase(pmio->plistContext, ListNode(_pmioc),1 );
        return NULL;
    }
    #endif
    return _pmioc;
}

int MioTimerClose(mio_t* pmio, miocontext_t* pmiocTimer)
{
    int ret = MioTimerUninit(pmio, pmiocTimer);
    ListErase(pmio->plistContext, ListNode(pmiocTimer),1 );
    return ret;
}

int MioTimerUninit(mio_t* pmio, miocontext_t* pmiocTimer)
{
    int ret = 0;
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmiocTimer->sock != (SOCKET)NULL) //停止计数器
    {
        DeleteTimerQueueTimer(NULL,(HANDLE)pmiocTimer->sock,INVALID_HANDLE_VALUE);  pmiocTimer->sock= (SOCKET)NULL;
    }
    #elif defined(__linux__)
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD,pmiocTimer->sock, NULL) )
    {
        ret = -1;
    }
    if(-1 == close(pmiocTimer->sock))
    {
        ret = -1;
    }
    #endif
    Array2Uninit(&pmiocTimer->d.timer.arrTimer);
    return ret;
}

int MioTimerOverlapped(mio_t* pmio, miocontext_t* pmioc)
{
    struct timespec _min = {.tv_sec = LONG_MAX, .tv_nsec = LONG_MAX}; // 最早的时间
    miotimer_t* _pmiot = NULL;
    for(int i = Array2Size(&pmioc->d.timer.arrTimer) - 1; i >= 0; i-- )
    {
        miotimer_t* pmiot = Array2At3(&pmioc->d.timer.arrTimer,i);
        if(pmiot->valid && 
            (pmiot->arriveTime.tv_sec < _min.tv_sec || 
                (pmiot->arriveTime.tv_sec == _min.tv_sec &&
                   pmiot->arriveTime.tv_nsec< _min.tv_nsec )))
        {
            _min.tv_sec = pmiot->arriveTime.tv_sec;_min.tv_nsec = pmiot->arriveTime.tv_nsec;
            _pmiot = pmiot;
        }
    }
    // 获取当前时间
    if(_pmiot)
    {
        pmioc->d.timer.pmiot = _pmiot;
        #if defined(_WIN32) && defined(_MSC_VER)
        struct timespec now = {0}; timespec_get(&now,TIME_UTC);
        long long dt = (_pmiot->arriveTime.tv_sec -now.tv_sec) * 1000 + (long long)((_pmiot->arriveTime.tv_nsec - now.tv_nsec)/((long)1e9/1e3));
        DWORD DueTime = (DWORD)(dt<0?1:dt);
        if(FALSE == CreateTimerQueueTimer((PHANDLE)&pmioc->sock,NULL,_MioTimerRoutine,pmioc,DueTime,0,WT_EXECUTEDEFAULT))
        {
            return -1;
        }
        #elif defined(__linux__)
        // struct timespec boot = {0}; //系统启动开始计时到当前的时间
        // clock_gettime(CLOCK_MONOTONIC_COARSE, &boot);
        struct epoll_event ev = {.events =  EPOLLIN | EPOLLET |EPOLLERR | EPOLLRDHUP | EPOLLONESHOT, .data.ptr = pmioc,};
        if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_MOD,pmioc->sock, &ev) )
        {
            return -1;
        }
        struct itimerspec utmr = {.it_value = {.tv_sec=_pmiot->arriveTime.tv_sec, .tv_nsec = _pmiot->arriveTime.tv_nsec}};
        // struct itimerspec utmr = {.it_value = {.tv_sec=1, .tv_nsec = 0,},};
        if(-1 == timerfd_settime(pmioc->sock, TFD_TIMER_ABSTIME, &utmr, NULL)) 
        {
            return -1;
        }
        #endif
    }
    return 0;
}

miotimer_t* _MioTimerSet(miocontext_t* pmiocTimer, miotimer_t* _pmiot, int type, va_list ap)
{
    struct timespec now = {0};
    #if defined(_WIN32) && defined(_MSC_VER)
    timespec_get(&now,TIME_UTC);
    #elif defined(__linux__)
    clock_gettime(CLOCK_REALTIME_COARSE, &now);
    #endif
    _pmiot->type = type;
    _pmiot->valid = 1;
    _pmiot->id = pmiocTimer->d.timer.ID++;
    if(type == MIO_TIMER_DELAY)
    {
        unsigned long delay = va_arg(ap, unsigned long);  // 延时时间，单位毫秒
        _pmiot->period = va_arg(ap, unsigned long); // 重复间隔，单位毫秒，0表示无重复
        _pmiot->arriveTime.tv_sec = now.tv_sec + delay / 1000;
        _pmiot->arriveTime.tv_nsec = now.tv_nsec + (delay % 1000);DebugPrint("MIO_TIMER_DELAY: %lu\n",delay);
        if(_pmiot->arriveTime.tv_nsec> (long)(1e9))
        {
            _pmiot->arriveTime.tv_sec++; _pmiot->arriveTime.tv_nsec -= (long)(1e9);
        }
    }
    else if(type == MIO_TIMER_AT)
    {
        // 8个参数 int:年;int:月;int:日;int:时;int:分;int:秒;int:毫秒;unsigned long:period 触发周期间隔 单位 毫秒，0表示无重复;
        struct tm st ={0};
        st.tm_year = va_arg(ap, int) - 1900; st.tm_mon = va_arg(ap, int) - 1;
        st.tm_mday = va_arg(ap, int); st.tm_hour = va_arg(ap, int);
        st.tm_min = va_arg(ap, int); st.tm_sec = va_arg(ap, int);
        long nsec = (long)( 1e9 / 1e3 )* (((int)va_arg(ap, int))%((long)1e3)); // //修正输入
        time_t tt = mktime(&st);DebugPrint("MIO_TIMER_AT: %lld\n",tt);
        if(-1 == tt) {return NULL;}//时间转换错误退出
        _pmiot->period = va_arg(ap, unsigned long); //重复间隔，0表示无重复
        _pmiot->arriveTime.tv_sec = tt;
        _pmiot->arriveTime.tv_nsec = nsec; //修正输入
    }
    else if(type == MIO_TIMER_DAY)
    {
        // 个参数 int:触发日周期间隔 单位:日;int:时;int:分;int:秒;
        unsigned int period_day = va_arg(ap, int); //第一个参数为日期的周期
        struct tm st ={0}; //从参数获取的 时分秒毫秒
        st.tm_hour = va_arg(ap, int); st.tm_min = va_arg(ap, int); st.tm_sec = va_arg(ap, int);
        struct tm *tmnow = localtime(&now.tv_sec); //转换为 struct tm 格式以获取年月日
        st.tm_year = tmnow->tm_year; st.tm_mon = tmnow->tm_mon;st.tm_mday = tmnow->tm_mday;
        time_t ttst = mktime(&st);//设定时间 localtime 转换成 unix时间戳，用于和当前
        if(ttst < now.tv_sec ) // 设定的时间小于当前时间，到下一个周期再触发
        {
            st.tm_mday += period_day; mktime(&st); //使用 mktime修正下一个周期的时间
        }
        time_t tt = mktime(&st); //计算触发时间
        _pmiot->arriveTime.tv_sec = tt;
        _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MIO_TIMER_DAY: %lu\n",tt);
        st.tm_mday = period_day; //把 period_month 月周期保存在 _pmiot->period 中
        _pmiot->period = ((st.tm_sec&0b111111)<<0)|((st.tm_min&0b111111)<<6)|((st.tm_hour&0b11111)<<12)|((period_day)<<17); //把下次时间保存在 _pmiot->period 中
    }
    else if(type == MIO_TIMER_MONTH)
    {
        unsigned int period_month = va_arg(ap, int);
        struct tm st ={0}; //从参数获取的 日时分秒毫秒
        st.tm_mday = va_arg(ap, int); st.tm_hour = va_arg(ap, int);
        st.tm_min = va_arg(ap, int); st.tm_sec = va_arg(ap, int);
        struct tm *tmnow = localtime(&now.tv_sec);
        st.tm_year = tmnow->tm_year; st.tm_mon = tmnow->tm_mon;
        time_t ttst = mktime(&st);//设定时间 localtime 转换成 unix时间戳
        if(ttst < now.tv_sec ) // 设定的时间小于当前时间，到下一个周期年再触发
        {
            st.tm_mon += period_month;mktime(&st); //重新计算时间
        }
        time_t tt = mktime(&st); //计算触发时间
        _pmiot->arriveTime.tv_sec = tt;
        _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MIO_TIMER_MONTH: %lu\n",tt);
        st.tm_yday = 0; st.tm_mon = period_month; //把 period_month 月周期保存在 _pmiot->period 中
        _pmiot->period = ((st.tm_sec&0b111111)<<0)|((st.tm_min&0b111111)<<6)|((st.tm_hour&0b11111)<<12)|
                ((st.tm_mday&0b11111)<<17)|((period_month)<<22); //把下次时间保存在 _pmiot->period 中
    }
    else if(type == MIO_TIMER_YEAR)
    {
        unsigned int period_year = va_arg(ap, int);
        struct tm st ={0}; //从参数获取的 月日时分秒毫秒
        st.tm_mon = va_arg(ap, int) - 1;
        st.tm_mday = va_arg(ap, int); st.tm_hour = va_arg(ap, int);
        st.tm_min = va_arg(ap, int); st.tm_sec = va_arg(ap, int);
        struct tm *tmnow = localtime(&now.tv_sec);
        st.tm_year = tmnow->tm_year;
        time_t ttst = mktime(&st);//设定时间 localtime 转换成 unix时间戳S
        if(ttst < now.tv_sec ) // 设定的时间小于当前时间，到下一个周期年再触发
        {
            st.tm_year += period_year;
        }
        time_t tt = mktime(&st); //计算触发时间
        _pmiot->arriveTime.tv_sec = tt;
        _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MIO_TIMER_YEAR: %lu\n",tt);
        st.tm_year = period_year;
        _pmiot->period = ((st.tm_sec&0b111111)<<0)|((st.tm_min&0b111111)<<6)|((st.tm_hour&0b11111)<<12)|
                ((st.tm_mday&0b11111)<<17)|((st.tm_mon&0b11111)<<22)|((period_year)<<26); //把下次时间保存在 _pmiot->period 中

    }
    DebugPrint("ID:%d\n", _pmiot->id);
    return _pmiot;
}

miotimer_t* MioTimerAdd(miocontext_t* pmiocTimer,int type, ...)
{
    va_list ap;
    va_start(ap, type);
    miotimer_t* _pmiot = Array2Push(&pmiocTimer->d.timer.arrTimer, NULL);
    if(_pmiot == NULL)
    {
        va_end(ap);
        return NULL;
    }
    miotimer_t * pmiot_r = _MioTimerSet(pmiocTimer, _pmiot, type,ap);
    va_end(ap);
    if(pmiot_r == NULL)
    {
        Array2Pop(&pmiocTimer->d.timer.arrTimer);
        return NULL;
    }
    return pmiot_r;
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    #endif
}

miotimer_t* MioTimerSet(miocontext_t* pmiocTimer, miotimer_t* _pmiot, int type, ...)
{
    va_list ap;
    va_start(ap, type);
    miotimer_t * pmiot_r = _MioTimerSet(pmiocTimer, _pmiot, type,ap);
    va_end(ap);
    return pmiot_r;
}

void MioTimerDel(miocontext_t* pmiocTimer, miotimer_t* pmiot)
{
    if(pmiocTimer->d.timer.pmiot == pmiot ) //当前正在计时
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        if(pmiocTimer->sock != (SOCKET)NULL)
        {
            DeleteTimerQueueTimer(NULL,(HANDLE)pmiocTimer->sock,INVALID_HANDLE_VALUE);  pmiocTimer->sock= (SOCKET)NULL;
        }
        #elif defined(__linux__)
        struct itimerspec utmr = {0};
        timerfd_settime(pmiocTimer->sock, TFD_TIMER_ABSTIME, &utmr, NULL);
        #endif
        pmiot->valid = 0;
        pmiocTimer->d.timer.pmiot = 0;
    }
    Array2Erase(&pmiocTimer->d.timer.arrTimer, (Array2Pos(&pmiocTimer->d.timer.arrTimer,pmiot)),1);
}

miotimer_t* MioTimerGetFired(miocontext_t* pmiocTimer)
{
    miotimer_t *_pmiot = pmiocTimer->d.timer.pmiot;
    #if defined(_WIN32) && defined(_MSC_VER)
    if(pmiocTimer->sock != (SOCKET)NULL)
    {
        DeleteTimerQueueTimer(NULL,(HANDLE)pmiocTimer->sock,NULL);pmiocTimer->sock = (SOCKET)NULL;
    }
    #elif defined(__linux__)
    uint64_t n = 0; 
    int ret = read(pmiocTimer->sock, &n, sizeof(n));
    if(ret == -1)
    {
        return NULL;
    }
    #endif
    if(_pmiot->period) //处理间隔的情况
    {
        struct timespec now = {0};
        #if defined(_WIN32) && defined(_MSC_VER)
        timespec_get(&now,TIME_UTC);
        #elif defined(__linux__)
        clock_gettime(CLOCK_REALTIME_COARSE, &now);
        #endif
        switch (_pmiot->type)
        {
        case MIO_TIMER_DELAY:case MIO_TIMER_AT:
        {
            _pmiot->arriveTime.tv_sec = now.tv_sec + _pmiot->period / 1000;
            _pmiot->arriveTime.tv_nsec = now.tv_nsec + (_pmiot->period % 1000) * ((long) (1e9/1e3));
            if(_pmiot->arriveTime.tv_nsec> (long)(1e9))
            {
                _pmiot->arriveTime.tv_sec++; _pmiot->arriveTime.tv_nsec -= (long)(1e9);
            }DebugPrint("MioTimerGetFired:%d: %lld.%d\n",_pmiot->id,_pmiot->arriveTime.tv_sec,_pmiot->arriveTime.tv_nsec);
        } break;
        case MIO_TIMER_DAY:
        {
            struct tm st = {.tm_mday=((_pmiot->period)>>17),.tm_hour=(((_pmiot->period)>>12)&0b11111),
                .tm_min=(((_pmiot->period)>>6)&0b111111),.tm_sec=(((_pmiot->period)>>0)&0b111111),};
            struct tm* pstnow = localtime(&now.tv_sec); // 当前时间
            st.tm_year=pstnow->tm_year;st.tm_mon=pstnow->tm_mon; st.tm_mday += pstnow->tm_mday; mktime(&st); //重新计算时间
            time_t tt = mktime(&st); //计算触发时间
            _pmiot->arriveTime.tv_sec = tt;
            _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MioTimerGetFired:%d:MIO_TIMER_DAY %lld\n",_pmiot->id,tt);
        } break;
        case MIO_TIMER_MONTH:
        {
            struct tm st = {.tm_mon=((_pmiot->period)>>22),.tm_mday=(((_pmiot->period)>>17)&0b11111),
                .tm_hour=(((_pmiot->period)>>12)&0b11111),.tm_min=(((_pmiot->period)>>6)&0b111111),.tm_sec=(((_pmiot->period)>>0)&0b111111),};
            struct tm* pstnow = localtime(&now.tv_sec); // 当前时间
            st.tm_year=pstnow->tm_year; st.tm_mon += pstnow->tm_mon;mktime(&st); //重新计算时间
            time_t tt = mktime(&st); //计算触发时间
            _pmiot->arriveTime.tv_sec = tt;
            _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MioTimerGetFired:%d:MIO_TIMER_MONTH %lld\n",_pmiot->id,tt);
        } break;
        case MIO_TIMER_YEAR:
        {
            struct tm st = {.tm_year=((_pmiot->period)>>26),.tm_mon=(((_pmiot->period)>>22)&0b1111),.tm_mday=(((_pmiot->period)>>17)&0b11111),
                .tm_hour=(((_pmiot->period)>>12)&0b11111),.tm_min=(((_pmiot->period)>>6)&0b111111),.tm_sec=(((_pmiot->period)>>0)&0b111111),};
            struct tm* pstnow = localtime(&now.tv_sec); // 当前时间
            st.tm_year += pstnow->tm_year;
            time_t tt = mktime(&st); //计算触发时间
            _pmiot->arriveTime.tv_sec = tt;
            _pmiot->arriveTime.tv_nsec = 0;DebugPrint("MioTimerGetFired:%d:MIO_TIMER_YEAR %lld\n",_pmiot->id,tt);
        } break;
        default:
            break;
        }
    }
    else
    {
        _pmiot->valid = 0;
    }
    pmiocTimer->d.timer.pmiot = NULL;
    return _pmiot;
}


#define MIO_TASKER_WATCHDOG_PERIOD 100  // tasker watchdog 的 循环时间，单位毫秒
/**
 * @brief _MioTaskerThreadFunction 的参数
 * 
 */
typedef struct miotaskerthreadparam_t
{
    int cntTaskerToDel; //标记是否有需要删除，由监视线程删除
    miotasker_t* pmiotasker; // 用于返回已完成的 miotasker_t*
    #if defined(_WIN32) && defined(_MSC_VER)
    HANDLE hSemaphore; //用于任务线程抢占任务,MioTaskerSet 发送信号,任务线程接收信号
    HANDLE hMutex; //用于保护任务数据,任何时只有一个线程在读写push/pop/move _pmioc->d.tasker.plistTasker
    HANDLE hEvent; // 用于任务线程完成任务时向MioWait 发送信号,任何时只会有一个任务线程可以发送,调用MioTaskerOverlapped后可以再次发送
    HANDLE hThread; // 用于监视线程
    #elif defined(__linux__)
    sem_t sem;
    pthread_mutex_t mutex;
    int event;
    pthread_t tid;
    #endif
}miotaskerthreadparam_t;

#if defined(_WIN32) && defined(_MSC_VER)
/**
 * @brief 任务线程
 * 
 * @param lpParam 
 * @return DWORD 
 */
DWORD WINAPI _MioTaskerThreadFunction( LPVOID lpParam )
#elif defined(__linux__)
/**
 * @brief 任务线程
 * 
 * @param lpParam 
 * @return DWORD 
 */
void* _MioTaskerThreadFunction(void * lpParam)
#endif
{
    miocontext_t* _pmioc = (miocontext_t*)lpParam;
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)_pmioc->d.tasker.pmti+(_pmioc->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    struct miothreadinfo_t* pmti = NULL;
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        DWORD tid = GetCurrentThreadId();
        #elif defined(__linux__)
        pthread_t tid = pthread_self();
        #endif
        for(int i = 0; i != _pmioc->d.tasker.cntTasker; i++)
        {
            if(_pmioc->d.tasker.pmti[i].tid == tid)
            {
                pmti = &_pmioc->d.tasker.pmti[i];
            }
        }
        assert(pmti);
    }
    while(1)
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        InterlockedExchange(&pmti->timeout, 0); // 清零定时器
        if(WAIT_OBJECT_0 !=  WaitForSingleObject(pmttp->hSemaphore,INFINITE))
        {
            return -1;
        }
        #elif defined(__linux__)
        __sync_fetch_and_and(&pmti->timeout,0); // 清零定时器
        int r = sem_wait(psem);
        if(r == -1)
        {
            return NULL;
        }
        // __sync_fetch_and_sub(&_pmioc->d.tasker.cntPending,1);// 原子减1
        #endif
        miotasker_t * pmiota = NULL;
        #if defined(_WIN32) && defined(_MSC_VER)
        if( WAIT_OBJECT_0 != WaitForSingleObject(pmttp->hMutex,INFINITE)){return -1;}
        #elif defined(__linux__)
        if( 0!= pthread_mutex_lock(&pmttp->pmutex) ){return NULL;} //进入锁查找一个 可执行的任务,同时只让一个线程进入查找
        #endif
        for(listnode_t* pln = ListBack(_pmioc->d.tasker.plistTasker); pln != NULL; pln = ListNodePrev(pln))
        {
            miotasker_t * pmiotaTmp = ListNodeData(pln);
            if(pmiotaTmp->status == MIO_TASKER_STATUS_WAITTING)
            {
                pmiotaTmp->status = MIO_TASKER_STATUS_RUNNING; //立即转换成正在执，防止其它线程抢
                pmiota = pmiotaTmp;
                break;
            }
        }
        #if defined(_WIN32) && defined(_MSC_VER)
        ReleaseMutex(pmttp->hMutex); // 释放这个锁
        #elif defined(__linux__)
        pthread_mutex_unlock(&pmttp->mutex);
        #endif
        if(pmiota) // 检索到一个正在等待执行的任务，转换其状态为正在执行
        {
            pmiota->pmti = pmti;
            #if defined(_WIN32) && defined(_MSC_VER)
            InterlockedExchangePointer(&pmti->pmiota,pmiota);
            #elif defined(__linux__)
            pmti->pmiota = pmiota;
            #endif
            pmti->pmiota->ret = pmti->pmiota->funtasker(pmti->pmiota->params);//执行任务
            pmti->pmiota->status = MIO_TASKER_STATUS_COMPLETE; //执行完成
            // //把已完成的 pmiota 移动到队列开始
            // #if defined(_WIN32) && defined(_MSC_VER)
            // if( WAIT_OBJECT_0 != WaitForSingleObject(pmttp->hMutex,INFINITE)){return -1;}
            // #elif defined(__linux__)
            // if( 0!= pthread_mutex_lock(&pmttp->mutex) ){return NULL;}
            // #endif
            // for(listnode_t* pln = ListFront(_pmioc->d.tasker.plistTasker); pln != NULL; pln = ListNodeNext(pln))
            // {
            //     miotasker_t * pmiotaTmp = ListNodeData(pln);
            //     if(pmiotaTmp->status != MIO_TASKER_STATUS_COMPLETE)
            //     {
            //         ListMoveBefore(_pmioc->d.tasker.plistTasker,ListNode(pmiotaTmp) ,ListNode(pmiota));
            //         break;
            //     }
            // }
            // #if defined(_WIN32) && defined(_MSC_VER)
            // // InterlockedIncrement(&_pmioc->d.tasker.cntFinishing); //在互斥中原子加1
            // ReleaseMutex(pmttp->hMutex);
            // #elif defined(__linux__)
            // pthread_mutex_unlock(&pmttp->mutex);
            // #endif
            #if defined(_WIN32) && defined(_MSC_VER)
            WaitForSingleObject(pmttp->hEvent,INFINITE); //等待允许向  MioWait 发送信号
            pmttp->pmiotasker = pmti->pmiota; //用于调用 MioTaskerGetFired 时返回 miotasker_t*
            PostQueuedCompletionStatus((HANDLE)_pmioc->sock, pmiota->id, (ULONG_PTR)_pmioc,&_pmioc->olRecv); //向 MioWait 发送完成标志
            #elif defined(__linux__)
            long long int buf = 1;
            write(_pmioc->sock, &buf, sizeof(long long int));// 通知 MioWait()
            #endif
            pmti->pmiota->pmti = NULL;
            #if defined(_WIN32) && defined(_MSC_VER)
            InterlockedExchangePointer(&pmti->pmiota,NULL);
            #elif defined(__linux__)
            pmti->pmiota = NULL;
            #endif
        }
    }
    return 0;
}

#if defined(_WIN32) && defined(_MSC_VER)
/**
 * @brief watchdog 线程，监管 tasker 线程
 * 
 * @param lpParam 
 * @return DWORD 
 */
DWORD WINAPI _MioTaskerWatchdogThreadFunction( LPVOID lpParam )
#elif defined(__linux__)
/**
 * @brief watchdog 线程，监管 tasker 线程
 * 
 * @param lpParam 
 * @return DWORD 
 */
void* _MioTaskerWatchdogThreadFunction(void * lpParam)
#endif
{
    miocontext_t* _pmioc = (miocontext_t*)lpParam;
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)_pmioc->d.tasker.pmti+(_pmioc->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
    #endif
    while(1)
    {
        // 检查任务线程
        for(int i =0; i != _pmioc->d.tasker.cntTasker; i++)
        {
            struct miothreadinfo_t * pmti = &_pmioc->d.tasker.pmti[i];
            #if defined(_WIN32) && defined(_MSC_VER)
            if(pmti->hThread == NULL)
            {
                pmti->hThread = CreateThread(NULL,0, _MioTaskerThreadFunction, (LPVOID)_pmioc,  0,&pmti->tid);
                DebugPrint("hThread:%p-%d create\n",pmti->hThread,pmti->tid);
            }
            #elif defined(__linux__)
            if(pmti->tid == -1)
            {
                if(0 != pthread_create(&pmti->tid, NULL, _MioTaskerThreadFunction,_pmioc))
                {
                    pmti->tid = -1;
                }
            }
            #endif
            else if(pmti->pmiota && pmti->pmiota->timeout ) //正在执行任务并且
            {
                if(pmti->timeout >= pmti->pmiota->timeout ) //有超时 //Int类型在对齐时读写是原子的,所以此处pmti->timeout可以直接读
                {
                    #if defined(_WIN32) && defined(_MSC_VER)
                    WaitForSingleObject(pmttp->hMutex,INFINITE);//防止目标线程又抢到了 mutex
                    #elif defined(__linux__)
                    pthread_mutex_lock(&pmttp->mutex); //防止目标线程又抢到了 mutex
                    #endif
                    if(
                    #if defined(_WIN32) && defined(_MSC_VER)
                    FALSE != TerminateThread(pmti->hThread,-1) //结束超时的线程
                    #elif defined(__linux__)
                    0 == pthread_cancel(pmti->tid) //结束超时的线程
                    #endif
                    )
                    {
                        if(
                            #if defined(_WIN32) && defined(_MSC_VER)
                            0 ==  WaitForSingleObject(pmti->hThread,INFINITE) //等待线程结束
                            #elif defined(__linux__)
                            0 == pthread_join(pmti->tid, NULL)//等待线程结束
                            #endif
                            )
                        {
                            miotasker_t * pmiota = pmti->pmiota;
                            #if defined(_WIN32) && defined(_MSC_VER)
                            InterlockedExchange(&pmti->timeout,0); // 清零定时器
                            InterlockedExchangePointer(&pmti->pmiota,NULL); // 将与线程关联的miotasker_t*清除
                            pmti->hThread = NULL;
                            #elif defined(__linux__)
                            __sync_fetch_and_and(&pmti->timeout,0); // 清零定时器
                            pmti->pmiota = NULL;
                            pmti->tid = -1;
                            #endif
                            pmiota->status = MIO_TASKER_STATUS_TIMEOUT; // 状态转换为 超时
                            pmiota->pmti = NULL;
                            #if defined(_WIN32) && defined(_MSC_VER)
                            WaitForSingleObject(pmttp->hEvent,INFINITE); //等待允许向  MioWait 发送信号
                            pmttp->pmiotasker = pmiota; //用于调用 MioTaskerGetFired 时返回 miotasker_t*
                            PostQueuedCompletionStatus((HANDLE)_pmioc->sock, pmiota->id, (ULONG_PTR)_pmioc,&_pmioc->olRecv); //向 MioWait 发送超时
                            pmti->hThread = CreateThread(NULL,0, _MioTaskerThreadFunction, (LPVOID)_pmioc,  0,&pmti->tid);
                            DebugPrint("hThread:%p-%d recreate\n",pmti->hThread,pmti->tid);
                            #elif defined(__linux__)
                            long long int buf = pmiota->id;
                            read(pmttp->event,&buf,sizeof(long long int)); //等待调用 MioTaskerOverlapped
                            buf = 1;
                            write(_pmioc->sock, &buf, sizeof(long long int));; // 通知 MioWait()超时
                            if(0 != pthread_create(&pmti->tid, NULL, _MioTaskerThreadFunction,_pmioc)) //再次重启线程
                            {
                                pmti->tid = -1;
                            }
                            #endif
                        }
                    }
                    #if defined(_WIN32) && defined(_MSC_VER)
                    ReleaseMutex(pmttp->hMutex);
                    #elif defined(__linux__)
                    pthread_mutex_unlock(&pmttp->mutex);
                    #endif
                }
                else
                {
                    #if defined(_WIN32) && defined(_MSC_VER)
                    InterlockedIncrement(&pmti->timeout); //  定时器加1
                    #elif defined(__linux__)
                    __sync_fetch_and_add(&pmti->timeout,1); //  定时器加1
                    #endif                    
                }
            }
        }
        //查找标记删除的任务，标记删除的任不返回任务状态
        if(pmttp->cntTaskerToDel)
        {
            #if defined(_WIN32) && defined(_MSC_VER)
            WaitForSingleObject(pmttp->hMutex,INFINITE);//防止目标线程又抢到了 mutex
            #elif defined(__linux__)
            pthread_mutex_lock(&pmttp->mutex); //防止目标线程又抢到了 mutex
            #endif
            for(listnode_t* pln = ListFront(_pmioc->d.tasker.plistTasker); pln != NULL; pln = ListNodeNext(pln))
            {
                miotasker_t * pmiotaTmp = ListNodeData(pln);
                if(pmiotaTmp->status == MIO_TASKER_STATUS_DEL)
                {
                    if(pmiotaTmp->pmti && pmiotaTmp->pmti->pmiota == pmiotaTmp)
                    {
                        if(
                        #if defined(_WIN32) && defined(_MSC_VER)
                        FALSE != TerminateThread(pmiotaTmp->pmti->hThread,-1) //结束超时的线程
                        #elif defined(__linux__)
                        0 == pthread_cancel(pmti->tid) //结束超时的线程
                        #endif
                        )
                        {
                            #if defined(_WIN32) && defined(_MSC_VER)
                            WaitForSingleObject(pmiotaTmp->pmti->hThread,INFINITE); //等待线程结束
                            InterlockedExchange(&pmiotaTmp->pmti->timeout,0); // 清零定时器
                            InterlockedExchangePointer(&pmiotaTmp->pmti->pmiota,NULL); // 将与线程关联的miotasker_t*清除
                            #elif defined(__linux__)
                            pthread_join(pmti->tid, NULL);//等待线程结束
                            pmiotaTmp->pmti->tid = -1;
                            pmiotaTmp->pmti->pmiota = NULL;
                            #endif
                        }
                    }
                    ListErase(_pmioc->d.tasker.plistTasker,ListNode(pmiotaTmp),1); //删除这个节点
                    #if defined(_WIN32) && defined(_MSC_VER)
                    InterlockedDecrement(&pmttp->cntTaskerToDel); // 需要删除的数减一
                    #elif defined(__linux__)
                    __sync_fetch_and_sub(&pmttp->cntTaskerToDel,1); //  需要删除的数减一
                    #endif
                }
            }
            #if defined(_WIN32) && defined(_MSC_VER)
            ReleaseMutex(pmttp->hMutex);
            #elif defined(__linux__)
            pthread_mutex_unlock(&pmttp->mutex);
            #endif
        }

        #if defined(_WIN32) && defined(_MSC_VER)
        Sleep(MIO_TASKER_WATCHDOG_PERIOD); // 监视线程休息 100ms//每 MIO_TASKER_WATCHDOG_PERIOD 时间循环一次，单位毫秒
        #elif defined(__linux__)
        usleep(MIO_TASKER_WATCHDOG_PERIOD* (long)(1e6/1e3)); // 监视线程休息 100ms//每 MIO_TASKER_WATCHDOG_PERIOD 时间循环一次，单位毫秒
        #endif
    }
    // #endif
    return 0;
}

miocontext_t* MioTaskerOpen(mio_t* pmio, unsigned int cntTasker)
{
    miocontext_t* _pmioc = MioAllocContext(pmio);
    if(pmio != NULL)
    {
        if(NULL == MioTaskerInit(pmio,_pmioc,cntTasker))
        {
            ListErase(pmio->plistContext,ListNode(_pmioc) ,1);_pmioc = NULL;
        }
    }
    return _pmioc;
}

miocontext_t* MioTaskerInit(mio_t* pmio, miocontext_t* pmioc, unsigned int cntTasker)
{
    unsigned int _szMem = (cntTasker)*sizeof(miothreadinfo_t)+sizeof(miotaskerthreadparam_t)+ListMemUsed(sizeof(miotasker_t), cntTasker*3);
    pmioc->d.tasker.pmti = (miothreadinfo_t*)malloc(_szMem);
    if(pmioc->d.tasker.pmti == NULL)
    {
        goto _fun_MioOpenTasker_ERR;
    }
    memset(pmioc->d.tasker.pmti, 0, _szMem);
    pmioc->d.tasker.ID = 1;
    pmioc->d.tasker.cntTasker = cntTasker;
    // pmioc->d.tasker.cntFinishing = 0;
    pmioc->type = MIO_TYPE_TASKER;
    pmioc->d.tasker.plistTasker = (list_t *)((char*)pmioc->d.tasker.pmti+(cntTasker)*sizeof(miothreadinfo_t)+sizeof(miotaskerthreadparam_t));
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)pmioc->d.tasker.pmti+(cntTasker)*sizeof(miothreadinfo_t));
    pmttp->cntTaskerToDel = 0;
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    pmioc->sock = -1;
    pmttp->tid = -1;
    for(int i =0; i != cntTasker; i++)
    {
        pmioc->d.tasker.pmti[i].tid = -1;
    }
    #endif
    if( NULL == ListInit(pmioc->d.tasker.plistTasker, sizeof(miotasker_t), cntTasker*3))
    {
        goto _fun_MioOpenTasker_ERR;
    }
    
    #if defined(_WIN32) && defined(_MSC_VER)
    if(NULL == (pmttp->hSemaphore = CreateSemaphore(NULL,0, cntTasker*3, NULL)) || 
        (NULL == (pmttp->hMutex = CreateMutex(NULL,FALSE,NULL))) ||
        (NULL == (pmttp->hEvent = CreateEvent(NULL,FALSE,FALSE,NULL))) ||
        (NULL == (pmttp->hThread = CreateThread(NULL,0, _MioTaskerWatchdogThreadFunction,(LPVOID)pmioc,0,NULL)))) 
    {
        goto _fun_MioOpenTasker_ERR;
    }
    pmioc->sock = (SOCKET)pmio->epfd; // 注意关闭 Tasker 时不能把 这个 epfd  关掉
    #elif defined(__linux__)
    if((-1 == sem_init(&pmttp->sem,0,0)) || 
        (-1 == pthread_mutex_init(&pmttp->mutex,NULL)) || 
        (-1 == (pmttp->event = eventfd(0, EFD_CLOEXEC))) ||
        (0 != pthread_create(&pmttp->tid,NULL,_MioTaskerWatchdogThreadFunction,pmioc)))  
    {
        goto _fun_MioOpenTasker_ERR;
    }
    struct epoll_event ev = {.events = EPOLLIN |EPOLLERR | EPOLLRDHUP, .data.ptr = pmioc };
    if(-1 == epoll_ctl(pmio->epfd, EPOLL_CTL_ADD, pmioc->sock, &ev) )
    {
        goto _fun_MioOpenTasker_ERR;
    }
    #endif
    return pmioc;
    _fun_MioOpenTasker_ERR:
    MioTaskerUninit(pmio, pmioc);
    return NULL;
}

void MioTaskerClose(mio_t* pmio, miocontext_t* pmiocTasker)
{
    MioTaskerUninit(pmio,pmiocTasker);
    ListErase(pmio->plistContext,ListNode(pmiocTasker),1);
}

void MioTaskerUninit(mio_t* pmio, miocontext_t* pmiocTasker)
{
    if(pmiocTasker)
    {
        if(pmiocTasker->d.tasker.pmti)
        {
            miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+(pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
            #if defined(_WIN32) && defined(_MSC_VER)
            if(pmttp->hThread)
            {
                TerminateThread(pmttp->hThread,-1); //结束监视线程
                WaitForSingleObject(pmttp->hThread,INFINITE); //等待线程结束
                pmttp->hThread = NULL;
            }
            if(pmttp->hMutex) {WaitForSingleObject(pmttp->hMutex,INFINITE);} //获得锁，并且不再释放，直接关闭
            #elif defined(__linux__)
            if(pmttp->tid != -1)
            {
                pthread_cancel(pmttp->tid); //结束监视线程
                pthread_join(pmttp->tid, NULL);//等待线程结束
                pmttp->tid = -1;                
            }
            #endif
            for(int i = 0; i != pmiocTasker->d.tasker.cntTasker; i++)
            {
                miothreadinfo_t * pmti = &pmiocTasker->d.tasker.pmti[i];
                #if defined(_WIN32) && defined(_MSC_VER)
                if(pmti->hThread)
                {
                    TerminateThread(pmti->hThread,-1); //结束超时的线程
                    WaitForSingleObject(pmti->hThread,INFINITE); //等待线程结束
                    pmti->hThread = NULL;                    
                }
                #elif defined(__linux__)
                if(pmti->tid != -1)
                {
                    pthread_cancel(pmti->tid); //结束监视线程
                    pthread_join(pmti->tid, NULL);//等待线程结束
                    pmti->tid = -1;                    
                }
                #endif
            }
            #if defined(_WIN32) && defined(_MSC_VER)
            if(pmttp->hSemaphore) {CloseHandle(pmttp->hSemaphore);pmttp->hSemaphore=NULL;}
            if(pmttp->hMutex) {CloseHandle(pmttp->hMutex);pmttp->hMutex=NULL;}
            if(pmttp->hEvent) {CloseHandle(pmttp->hEvent);pmttp->hEvent=NULL;}
            pmiocTasker->sock=(SOCKET)NULL;
            #elif defined(__linux__)
            if(pmiocTasker->sock != -1)
            {
                epoll_ctl(pmio->epfd, EPOLL_CTL_DEL,pmiocTasker->sock, NULL);
                close(pmiocTasker->sock)pmiocTasker->sock=-1;                
            }
            sem_destory(&pmttp->sem);
            pthread_mutex_destroy(&pmttp->mutex);
            close(pmttp->event);pmttp->event=-1;
            #endif
            free(pmiocTasker->d.tasker.pmti);
            pmiocTasker->d.tasker.pmti = NULL;
        }
    }
}

int MioTaskerOverlapped(mio_t* pmio, miocontext_t* pmiocTasker)
{
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+
                                        (pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    #if defined(_WIN32) && defined(_MSC_VER)
    UNREFERENCED_PARAMETER(pmio);
    SetEvent(pmttp->hEvent); // 触发允许工作线程完成工作时或监视线程发现超时时向MioWait() 发送信号
    #elif defined(__linux__)
    long long int buf = 1;
    write(pmttp->event, &buf, sizeof(long long int));; // 触发允许工作线程完成工作时或监视线程发现超时时向MioWait() 发送信号
    #endif
    return 0;
}

miotasker_t* MioTaskerSet(miocontext_t* pmiocTasker,miotasker_t* pmiota, int (*funtasker)(void*),void* params, unsigned long timeout)
{
    assert(pmiota->id != -1);
    if(funtasker)
    {
        pmiota->funtasker = funtasker;
        pmiota->params = params;
        pmiota->timeout = timeout / MIO_TASKER_WATCHDOG_PERIOD;
    }
    else
    {
        pmiota->status = MIO_TASKER_STATUS_NONE;
        return pmiota;
    }
    pmiota->status = MIO_TASKER_STATUS_WAITTING; // 等待执行
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+(pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    #if defined(_WIN32) && defined(_MSC_VER)
    // InterlockedIncrement(&pmiocTasker->d.tasker.cntPending); //原子加1
    ReleaseSemaphore(pmttp->hSemaphore,1,NULL); //触发任务线程抢任务
    #elif defined(__linux__)
    // __sync_fetch_and_add(&pmiocTasker->d.tasker.cntPending,1);
    if(-1 == sem_post(&pmttp->sem))
    {
        return NULL;
    }
    #endif
    return pmiota;
}

miotasker_t* MioTaskerAdd(miocontext_t* pmiocTasker,int (*funtasker)(void*),void* params, unsigned long timeout)
{
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)(miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+
            (pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    #if defined(_WIN32) && defined(_MSC_VER)
    if( WAIT_OBJECT_0 != WaitForSingleObject(pmttp->hMutex,INFINITE)){return NULL;}
    #elif defined(__linux__)
    if( 0!= pthread_mutex_lock(&pmttp->mutex) ){return NULL;}
    #endif
    miotasker_t* _pmiota = ListPush(pmiocTasker->d.tasker.plistTasker, NULL);
    #if defined(_WIN32) && defined(_MSC_VER)
    ReleaseMutex(pmttp->hMutex);
    #elif defined(__linux__)
    pthread_mutex_unlock(&pmttp->mutex);
    #endif
    if(_pmiota == NULL)
    {
        return NULL;
    }
    memset(_pmiota, 0, sizeof(miotasker_t));
    _pmiota->id = pmiocTasker->d.tasker.ID++;
    if(NULL== MioTaskerSet(pmiocTasker, _pmiota, funtasker, params, timeout))
    {
        #if defined(_WIN32) && defined(_MSC_VER)
        if( WAIT_OBJECT_0 != WaitForSingleObject(pmttp->hMutex,INFINITE)){return NULL;}
        #elif defined(__linux__)
        if( 0!= pthread_mutex_lock(&pmttp->mutex)){return NULL;}
        #endif
        ListErase(pmiocTasker->d.tasker.plistTasker,ListNode(_pmiota),1);
        #if defined(_WIN32) && defined(_MSC_VER)
        ReleaseMutex(pmttp->hMutex);
        #elif defined(__linux__)
        pthread_mutex_unlock(&pmttp->mutex);
        #endif
        _pmiota = NULL;
    }
    DebugPrint("add tasker,ID:%d\n", _pmiota->id);
    return _pmiota;
}

void MioTaskerDel(miocontext_t* pmiocTasker, miotasker_t* pmiota)
{
    if(pmiota->status != MIO_TASKER_STATUS_COMPLETE) //任务正在执行，需要通知 watchdog 线程终止
    {
        pmiota->status = MIO_TASKER_STATUS_DEL;
        miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)(miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+
            (pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
        InterlockedIncrement(&pmttp->cntTaskerToDel);
        // PostQueuedCompletionStatus(pmiocTasker->d.ptasker->epfdWatchdog, 2, (ULONG_PTR)pmiota,&pmiocTasker->olRecv);// 通知删除对象
    }
    else
    { //任务已完成直接删除
        ListErase(pmiocTasker->d.tasker.plistTasker,ListNode(pmiota),1);
    }
    #if defined(_WIN32) && defined(_MSC_VER)
    #elif defined(__linux__)
    #endif
}

miotasker_t* MioTaskerGetFired(miocontext_t* pmiocTasker)
{
    miotasker_t* pmiota = NULL;
    miotaskerthreadparam_t* pmttp = (miotaskerthreadparam_t*)((char*)pmiocTasker->d.tasker.pmti+(pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t));
    #if defined(_WIN32) && defined(_MSC_VER)
    pmiota = pmttp->pmiotasker;
    ReleaseMutex(pmttp->hMutex);
    #elif defined(__linux__)
    pthread_mutex_t* pmutex = (pthread_mutex_t*)((char*)pmiocTasker->d.tasker.pmti+
                        (pmiocTasker->d.tasker.cntTasker)*sizeof(miothreadinfo_t)+sizeof(sem_t));
    long long int buf = 0;
    if(8 != read(pmiocTasker->sock, (void*)&buf, sizeof(buf)))
    {
        return NULL;
    }
    #endif
    return pmiota;
}



#if defined(__linux__)
#undef SOCKET_ERROR 
#undef SOCKET
#undef closesocket
#endif